from datetime import datetime
from typing import Optional
from fastapi import APIRouter, Depends, Response
from sqlalchemy import and_, desc
from sqlalchemy.orm import Session
from customer.customer import verify_customer_token
from schemas.order import CreateOrderRequest, OrderModel
from utils.response import HTTPException
from db import get_db, crud, models
from schemas.customer import CustomerModel

router = APIRouter(prefix="/customer/order", tags=["客户订单"])


@router.post("", response_model=OrderModel, response_model_exclude_none=True)
def create_order(data: CreateOrderRequest,
                 customer: CustomerModel = Depends(verify_customer_token),
                 db: Session = Depends(get_db)):
    data.created_on = datetime.now()
    data.customer_id = customer.id

    db.query(models.ShoppingCart).filter(and_(
        models.ShoppingCart.customer_id == customer.id,
        models.ShoppingCart.status == 1,
        models.ShoppingCart.id.in_([i.id for i in data.items])
    )).update({
        "status": 0
    })

    return crud.Order.create(db, data)


@router.get("/count")
def get_count(customer: CustomerModel = Depends(verify_customer_token),
              db: Session = Depends(get_db)):
    unpaid = crud.Order.count_by_payment_status(db, customer.id, 1)
    not_shipped = crud.Order.count_by_shipping_status(db, customer.id, 1)
    in_shipped = crud.Order.count_by_shipping_status(db, customer.id, 2)

    return {
        "unpaid": unpaid,
        "not_shipped": not_shipped,
        "in_shipped": in_shipped,
    }


@router.get("/detail/{order_id}", response_model=OrderModel, response_model_exclude_none=True)
def get_order_detail(order_id: int,
                     customer: CustomerModel = Depends(verify_customer_token),
                     db: Session = Depends(get_db)):
    order = db.query(models.Order).filter(and_(
        models.Order.id == order_id,
        models.Order.customer_id == customer.id,
        models.Order.status != 0
    )).first()

    return order


@router.get("/all", response_model_exclude_none=True)
def get_order(order_status: Optional[int] = 1,
              customer: CustomerModel = Depends(verify_customer_token),
              db: Session = Depends(get_db)):
    orders = []

    if order_status == 1:
        orders = db.query(models.Order).filter(and_(
            models.Order.customer_id == customer.id,
            models.Order.status != 0
        )).order_by(desc(models.Order.id)).all()

    elif order_status == 2:
        orders = db.query(models.Order).filter(and_(
            models.Order.customer_id == customer.id,
            models.Order.status == 1,
            models.Order.payment_status == 1,
        )).order_by(desc(models.Order.id)).all()

    elif order_status == 3:
        orders = db.query(models.Order).filter(and_(
            models.Order.customer_id == customer.id,
            models.Order.status == 1,
            models.Order.payment_status == 2,
            models.Order.shipping_status == 1
        )).order_by(desc(models.Order.id)).all()

    elif order_status == 4:
        orders = db.query(models.Order).filter(and_(
            models.Order.customer_id == customer.id,
            models.Order.status == 1,
            models.Order.payment_status == 2,
            models.Order.shipping_status == 2
        )).order_by(desc(models.Order.id)).all()

    elif order_status == 5:
        orders = db.query(models.Order).filter(and_(
            models.Order.customer_id == customer.id,
            models.Order.status == 2,
        )).order_by(desc(models.Order.id)).all()

    elif order_status == 6:
        orders = db.query(models.Order).filter(and_(
            models.Order.customer_id == customer.id,
            models.Order.status == 3,
            models.Order.payment_status == 3
        )).order_by(desc(models.Order.id)).all()

    return orders


@router.put("/cancel/{order_id}")
def cancel_order(order_id: int,
                 customer: CustomerModel = Depends(verify_customer_token),
                 db: Session = Depends(get_db)):
    db.query(models.Order).filter_by(
        id=order_id,
        customer_id=customer.id,
        status=1,
        payment_status=1
    ).update({
        "updated_on": datetime.now(),
        "status": 3
    })
    db.commit()

    return Response()


@router.put("/payment/{order_id}")
def payment(order_id: int,
            customer: CustomerModel = Depends(verify_customer_token),
            db: Session = Depends(get_db)):
    order = db.query(models.Order).filter_by(
        id=order_id,
        customer_id=customer.id,
        status=1,
        payment_status=1
    ).first()

    if order is not None:
        order.updated_on = datetime.now()
        order.payment_date = datetime.now()
        order.payment_status = 2

        for i in order.items:
            if i["flower"]:
                flower = db.query(models.Flower).get(i["flower"]["id"])
                flower.sales_count += i["quantity"]

    else:
        raise HTTPException(message="订单状态异常")

    db.commit()

    return Response()


@router.put("/refund/{order_id}")
def refund(order_id: int,
           customer: CustomerModel = Depends(verify_customer_token),
           db: Session = Depends(get_db)):
    order = db.query(models.Order).filter_by(
        id=order_id,
        customer_id=customer.id,
        status=1,
        payment_status=2,
        shipping_status=1
    ).first()

    if order is not None:
        order.updated_on = datetime.now()
        order.status = 3
        order.payment_status = 3

        for i in order.items:
            if i["flower"]:
                flower = db.query(models.Flower).get(i["flower"]["id"])
                flower.sales_count -= i["quantity"]

        if order.delivery_person["id"]:
            delivery_person: models.DeliveryPerson = db.query(models.DeliveryPerson).get(order.delivery_person["id"])
            if delivery_person:
                delivery_person.delivering -= 1

    else:
        raise HTTPException(message="订单状态异常")

    db.commit()

    return Response()


@router.put("/confirm-receipt/{order_id}")
def confirm_receipt(order_id: int,
                    customer: CustomerModel = Depends(verify_customer_token),
                    db: Session = Depends(get_db)):
    order = db.query(models.Order).filter_by(
        id=order_id,
        customer_id=customer.id,
        status=1,
        payment_status=2
    ).first()

    if order is not None:
        order.shipping_status = 3
        order.status = 2

        if order.delivery_person["id"]:
            delivery_person: models.DeliveryPerson = db.query(models.DeliveryPerson).get(order.delivery_person["id"])
            if delivery_person:
                delivery_person.delivering -= 1
                delivery_person.delivery_count += 1

        db.commit()
    else:
        raise HTTPException(message="订单状态异常")

    return Response()
